package cn.com.efuture.o2o.backend.api.auth;


import cn.com.efuture.o2o.backend.mybatis.entity.User;
import cn.com.efuture.o2o.backend.security.JwtTokenUtil;
import cn.com.efuture.o2o.backend.security.entity.JwtAuthenticationRequest;
import cn.com.efuture.o2o.backend.security.entity.JwtAuthenticationResponse;
import cn.com.efuture.o2o.backend.system.JsonResponse;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.mobile.device.Device;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Eric on 2017-01-22.
 */
@RestController
@RequestMapping("/api")
public class AuthRestController {
    private final JwtTokenUtil jwtTokenUtil;

//    @Autowired
//    private AuthenticationManager authenticationManager;
    private final AuthenticationManager authenticationManagerBean;

    protected org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());

    public AuthRestController(JwtTokenUtil jwtTokenUtil, AuthenticationManager authenticationManagerBean) {
        this.jwtTokenUtil = jwtTokenUtil;
        this.authenticationManagerBean = authenticationManagerBean;
    }

    @ApiOperation(value = "登录后获取token", notes = "登录后获取token")
    @RequestMapping(value = "/auth", method = RequestMethod.POST)
    public JsonResponse authenticationRequest(@RequestBody JwtAuthenticationRequest authenticationRequest, Device device) throws AuthenticationException {

        try {
            // Perform the authentication
            Authentication requestAuth = new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword());
            Authentication resultAuth = authenticationManagerBean.authenticate(requestAuth);
            SecurityContextHolder.getContext().setAuthentication(resultAuth);

            // generate Token (User ID, Authorities, Device Type, Created Date)
            @SuppressWarnings("unchecked")
            Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>) resultAuth.getAuthorities();
            String commaSprAuthorities = StringUtils.join(authorities, ",");
            User loginUser = new User();
            loginUser.setUserName(resultAuth.getName());
            loginUser.setAuthorities(commaSprAuthorities);
            String token = this.jwtTokenUtil.generateToken(loginUser, device);
            return JsonResponse.ok(new JwtAuthenticationResponse(token));
        }catch (Exception e){
            logger.error(e.getMessage());
            return JsonResponse.notOk(e.getMessage());
        }
    }

    @RequestMapping(value = "/sessions", method = RequestMethod.GET)
    public Object sessions(HttpServletRequest request) {
        String username;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            username = ((UserDetails) principal).getUsername();
            logger.debug("-------1------" + username);
        } else {
            username = principal.toString();
            logger.debug("--------2-----" + username);
        }
        Map<String, Object> map = new HashMap<>();

        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map.put("sessionId", request.getSession().getId());
        map.put("token", request.getHeader("x-auth-token"));
        map.put("creationTime", sd.format(request.getSession().getCreationTime()));
        map.put("MaxInactive", request.getSession().getMaxInactiveInterval());
        map.put("LastAccessedTime", sd.format(request.getSession().getLastAccessedTime()));
        map.put("SPRING_SECURITY_CONTEXT", request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"));
        return map;
    }
}
